package it.gestoreContratti.gui.panels;

import it.gestoreContratti.database.DatabaseController;
import it.gestoreContratti.database.exception.DatabaseConnectionException;
import it.gestoreContratti.database.exception.QueryException;
import it.gestoreContratti.entity.Contratto;
import it.gestoreContratti.entity.Specifica;
import it.gestoreContratti.exception.EmptyFieldException;
import it.gestoreContratti.inputVerifiers.DateInputVerifier;
import it.gestoreContratti.inputVerifiers.NumericInputVerifier;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class ModificaSpecificaPanel extends JPanel {
	
	private static final long serialVersionUID = 374989618340576388L;
	private JTextField numeroContrattoTextField;
	private JTextField numeroSpecificaTextField;
	private JLabel rimanenzaContrattoLabel;
	private JTextField rimanenzaContrattoTextField;
	private JLabel dataScadenzaContrattoLabel;
	private JTextField dataScadenzaContrattoTextField;
	private JLabel dataInizioSpecificaLabel;
	private JTextField dataInizioSpecificaTextField;
	private JLabel termineConsegnaLabel;
	private JTextField termineConsegnaTextField;
	private JLabel dataScadenzaSpecificaLabel;
	private JTextField dataScadenzaSpecificaTextField;
	private JLabel importoSpecificaLabel;
	private JTextField importoSpecificaTextField;
	private JLabel lblDataInizioContratto;
	private JTextField dataInizioContrattoTextField;
	private JButton modificaSpecificaButton;
	private DateFormat dateFormat;
	private Contratto contratto;
	private DatabaseController databaseController;
	private BigDecimal numero;
	private Date dataInizio;
	private BigDecimal termineConsegna;
	private Date dataScadenza;
	private BigDecimal importo;
	private Specifica specifica;

	/**
	 * Create the panel.
	 */
	public ModificaSpecificaPanel(Contratto c, DatabaseController dbController, Specifica spec) {
		this.contratto = c;
		this.databaseController = dbController;
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{176, 0, 0};
		gridBagLayout.rowHeights = new int[]{0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0};
		gridBagLayout.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
		gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
		setLayout(gridBagLayout);
		
		this.dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		this.specifica = spec;
		JLabel numeroContrattoLabel = new JLabel("Numero Contratto");
		GridBagConstraints gbc_numeroContrattoLabel = new GridBagConstraints();
		gbc_numeroContrattoLabel.insets = new Insets(0, 0, 5, 5);
		gbc_numeroContrattoLabel.anchor = GridBagConstraints.EAST;
		gbc_numeroContrattoLabel.gridx = 0;
		gbc_numeroContrattoLabel.gridy = 0;
		add(numeroContrattoLabel, gbc_numeroContrattoLabel);
		
		numeroContrattoTextField = new JTextField();
		numeroContrattoTextField.setText(contratto.getNumero().toString());
		numeroContrattoTextField.setEditable(false);
		GridBagConstraints gbc_numeroContrattoTextField = new GridBagConstraints();
		gbc_numeroContrattoTextField.insets = new Insets(0, 0, 5, 0);
		gbc_numeroContrattoTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_numeroContrattoTextField.gridx = 1;
		gbc_numeroContrattoTextField.gridy = 0;
		add(numeroContrattoTextField, gbc_numeroContrattoTextField);
		numeroContrattoTextField.setColumns(10);
		
		lblDataInizioContratto = new JLabel("Data Inizio Contratto");
		GridBagConstraints gbc_lblDataInizioContratto = new GridBagConstraints();
		gbc_lblDataInizioContratto.anchor = GridBagConstraints.EAST;
		gbc_lblDataInizioContratto.insets = new Insets(0, 0, 5, 5);
		gbc_lblDataInizioContratto.gridx = 0;
		gbc_lblDataInizioContratto.gridy = 1;
		add(lblDataInizioContratto, gbc_lblDataInizioContratto);
		
		dataInizioContrattoTextField = new JTextField();
		dataInizioContrattoTextField.setText(dateFormat.format(contratto.getDataInizio()));
		dataInizioContrattoTextField.setEditable(false);
		GridBagConstraints gbc_dataInizioContrattoTextField = new GridBagConstraints();
		gbc_dataInizioContrattoTextField.insets = new Insets(0, 0, 5, 0);
		gbc_dataInizioContrattoTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_dataInizioContrattoTextField.gridx = 1;
		gbc_dataInizioContrattoTextField.gridy = 1;
		add(dataInizioContrattoTextField, gbc_dataInizioContrattoTextField);
		dataInizioContrattoTextField.setColumns(10);
		
		dataScadenzaContrattoLabel = new JLabel("Data Scadenza Contratto");		
		GridBagConstraints gbc_dataScadenzaContrattoLabel = new GridBagConstraints();
		gbc_dataScadenzaContrattoLabel.anchor = GridBagConstraints.EAST;
		gbc_dataScadenzaContrattoLabel.insets = new Insets(0, 0, 5, 5);
		gbc_dataScadenzaContrattoLabel.gridx = 0;
		gbc_dataScadenzaContrattoLabel.gridy = 2;
		add(dataScadenzaContrattoLabel, gbc_dataScadenzaContrattoLabel);
		
		dataScadenzaContrattoTextField = new JTextField();
		dataScadenzaContrattoTextField.setText(dateFormat.format(contratto.getDataScadenza()));
		dataScadenzaContrattoTextField.setEditable(false);
		GridBagConstraints gbc_dataScadenzaTextField = new GridBagConstraints();
		gbc_dataScadenzaTextField.insets = new Insets(0, 0, 5, 0);
		gbc_dataScadenzaTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_dataScadenzaTextField.gridx = 1;
		gbc_dataScadenzaTextField.gridy = 2;
		add(dataScadenzaContrattoTextField, gbc_dataScadenzaTextField);
		dataScadenzaContrattoTextField.setColumns(10);
		
		rimanenzaContrattoLabel = new JLabel("Rimanenza Contratto");
		GridBagConstraints gbc_rimanenzaContrattoLabel = new GridBagConstraints();
		gbc_rimanenzaContrattoLabel.anchor = GridBagConstraints.EAST;
		gbc_rimanenzaContrattoLabel.insets = new Insets(0, 0, 5, 5);
		gbc_rimanenzaContrattoLabel.gridx = 0;
		gbc_rimanenzaContrattoLabel.gridy = 3;
		add(rimanenzaContrattoLabel, gbc_rimanenzaContrattoLabel);
		
		rimanenzaContrattoTextField = new JTextField();
		rimanenzaContrattoTextField.setText(contratto.getRimanenza().toString());
		rimanenzaContrattoTextField.setEditable(false);
		GridBagConstraints gbc_rimanenzaContrattoTextField = new GridBagConstraints();
		gbc_rimanenzaContrattoTextField.insets = new Insets(0, 0, 5, 0);
		gbc_rimanenzaContrattoTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_rimanenzaContrattoTextField.gridx = 1;
		gbc_rimanenzaContrattoTextField.gridy = 3;
		add(rimanenzaContrattoTextField, gbc_rimanenzaContrattoTextField);
		rimanenzaContrattoTextField.setColumns(10);
		
		JLabel numeroSpecificaLabel = new JLabel("Numero Specifica");
		GridBagConstraints gbc_numeroSpecificaLabel = new GridBagConstraints();
		gbc_numeroSpecificaLabel.anchor = GridBagConstraints.EAST;
		gbc_numeroSpecificaLabel.insets = new Insets(0, 0, 5, 5);
		gbc_numeroSpecificaLabel.gridx = 0;
		gbc_numeroSpecificaLabel.gridy = 4;
		add(numeroSpecificaLabel, gbc_numeroSpecificaLabel);
		
		numeroSpecificaTextField = new JTextField();
		numeroSpecificaTextField.setInputVerifier(new NumericInputVerifier("Numero Specifica", 15));
		numeroSpecificaTextField.setText(specifica.getNumero().toString());
		GridBagConstraints gbc_numeroSpecificaLabelTextField = new GridBagConstraints();
		gbc_numeroSpecificaLabelTextField.insets = new Insets(0, 0, 5, 0);
		gbc_numeroSpecificaLabelTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_numeroSpecificaLabelTextField.gridx = 1;
		gbc_numeroSpecificaLabelTextField.gridy = 4;
		add(numeroSpecificaTextField, gbc_numeroSpecificaLabelTextField);
		numeroSpecificaTextField.setColumns(10);
		
		dataInizioSpecificaLabel = new JLabel("Data Inizio Specifica");
		GridBagConstraints gbc_dataInizioSpecificaLabel = new GridBagConstraints();
		gbc_dataInizioSpecificaLabel.anchor = GridBagConstraints.EAST;
		gbc_dataInizioSpecificaLabel.insets = new Insets(0, 0, 5, 5);
		gbc_dataInizioSpecificaLabel.gridx = 0;
		gbc_dataInizioSpecificaLabel.gridy = 5;
		add(dataInizioSpecificaLabel, gbc_dataInizioSpecificaLabel);
		
		dataInizioSpecificaTextField = new JTextField();
		dataInizioSpecificaTextField.setText(dateFormat.format(specifica.getDataInizio()));
		dataInizioSpecificaTextField.addFocusListener(new FocusAdapter() {
			@Override
			public void focusLost(FocusEvent arg0) {
				Calendar inizio = new GregorianCalendar();
				try{
					if(dataInizioSpecificaTextField.getText().length() !=0){
						inizio.setTime(dateFormat.parse(dataInizioSpecificaTextField.getText()));
						if(inizio.getTime().compareTo(contratto.getDataInizio()) < 0){
							JOptionPane.showMessageDialog(null, "La data di inizio della specifica deve essere successiva o uguale alla data di inizio del contratto", "", JOptionPane.WARNING_MESSAGE);
							dataInizioSpecificaTextField.setText("");
							dataInizioContrattoTextField.validate();
							return;
						}
						if(termineConsegnaTextField.getText().length() != 0){
							inizio.setTime(dateFormat.parse(dataInizioSpecificaTextField.getText()));
							if(inizio.getTime().compareTo(contratto.getDataInizio()) < 0){
								JOptionPane.showMessageDialog(null, "La data di inizio della specifica deve essere successiva o uguale alla data di inizio del contratto", "", JOptionPane.WARNING_MESSAGE);
								dataInizioSpecificaTextField.setText("");
								dataInizioContrattoTextField.validate();
								return;
							}
							BigDecimal termine = new BigDecimal(termineConsegnaTextField.getText());
							inizio.add(Calendar.DAY_OF_MONTH, termine.intValue());
							dataScadenzaSpecificaTextField.setText(dateFormat.format(inizio.getTime()));
							
						}
					}					
				} catch (ParseException e) {					
				}
			}
		});
		dataInizioSpecificaTextField.setInputVerifier(new DateInputVerifier("Data Inizio Specifica"));
		GridBagConstraints gbc_dataInizioSpecificaTextField = new GridBagConstraints();
		gbc_dataInizioSpecificaTextField.insets = new Insets(0, 0, 5, 0);
		gbc_dataInizioSpecificaTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_dataInizioSpecificaTextField.gridx = 1;
		gbc_dataInizioSpecificaTextField.gridy = 5;
		add(dataInizioSpecificaTextField, gbc_dataInizioSpecificaTextField);
		dataInizioSpecificaTextField.setColumns(10);
		
		termineConsegnaLabel = new JLabel("Termine Consegna(GG)");
		GridBagConstraints gbc_termineConsegnaLabel = new GridBagConstraints();
		gbc_termineConsegnaLabel.anchor = GridBagConstraints.EAST;
		gbc_termineConsegnaLabel.insets = new Insets(0, 0, 5, 5);
		gbc_termineConsegnaLabel.gridx = 0;
		gbc_termineConsegnaLabel.gridy = 6;
		add(termineConsegnaLabel, gbc_termineConsegnaLabel);
		
		termineConsegnaTextField = new JTextField();
		termineConsegnaTextField.setText(specifica.getTermineConsegna().toString());
		termineConsegnaTextField.addFocusListener(new FocusAdapter() {
			@Override
			public void focusLost(FocusEvent arg0) {
				if(dataInizioSpecificaTextField.getText().length() !=0 && termineConsegnaTextField.getText().length() != 0){
					try{
						Calendar inizio = new GregorianCalendar();
						inizio.setTime(dateFormat.parse(dataInizioSpecificaTextField.getText()));						
						BigDecimal termine = new BigDecimal(termineConsegnaTextField.getText());
						inizio.add(Calendar.DAY_OF_MONTH, termine.intValue());
						dataScadenzaSpecificaTextField.setText(dateFormat.format(inizio.getTime()));
					} catch (ParseException e) {						
					}catch (NumberFormatException e) {						
					}
				}
			}
		});
		termineConsegnaTextField.setInputVerifier(new NumericInputVerifier("Termine Consegna", 4));
		GridBagConstraints gbc_termineConsegnaTextField = new GridBagConstraints();
		gbc_termineConsegnaTextField.insets = new Insets(0, 0, 5, 0);
		gbc_termineConsegnaTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_termineConsegnaTextField.gridx = 1;
		gbc_termineConsegnaTextField.gridy = 6;
		add(termineConsegnaTextField, gbc_termineConsegnaTextField);
		termineConsegnaTextField.setColumns(10);
		
		dataScadenzaSpecificaLabel = new JLabel("Data Scadenza Specifica");
		GridBagConstraints gbc_dataScadenzaSpecificaLabel = new GridBagConstraints();
		gbc_dataScadenzaSpecificaLabel.anchor = GridBagConstraints.EAST;
		gbc_dataScadenzaSpecificaLabel.insets = new Insets(0, 0, 5, 5);
		gbc_dataScadenzaSpecificaLabel.gridx = 0;
		gbc_dataScadenzaSpecificaLabel.gridy = 7;
		add(dataScadenzaSpecificaLabel, gbc_dataScadenzaSpecificaLabel);
		
		dataScadenzaSpecificaTextField = new JTextField();
		dataScadenzaSpecificaTextField.setText(dateFormat.format(specifica.getDataScadenza()));
		dataScadenzaSpecificaTextField.setInputVerifier(new DateInputVerifier("Data Scadenza Specifica"));
		dataScadenzaSpecificaTextField.setEditable(false);
		GridBagConstraints gbc_dataScadenzaSpecificaTextField = new GridBagConstraints();
		gbc_dataScadenzaSpecificaTextField.insets = new Insets(0, 0, 5, 0);
		gbc_dataScadenzaSpecificaTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_dataScadenzaSpecificaTextField.gridx = 1;
		gbc_dataScadenzaSpecificaTextField.gridy = 7;
		add(dataScadenzaSpecificaTextField, gbc_dataScadenzaSpecificaTextField);
		dataScadenzaSpecificaTextField.setColumns(10);
		
		importoSpecificaLabel = new JLabel("Importo Specifica");
		GridBagConstraints gbc_importoSpecificaLabel = new GridBagConstraints();
		gbc_importoSpecificaLabel.anchor = GridBagConstraints.EAST;
		gbc_importoSpecificaLabel.insets = new Insets(0, 0, 5, 5);
		gbc_importoSpecificaLabel.gridx = 0;
		gbc_importoSpecificaLabel.gridy = 8;
		add(importoSpecificaLabel, gbc_importoSpecificaLabel);
		
		importoSpecificaTextField = new JTextField();
		importoSpecificaTextField.setText(specifica.getImporto().toString());
		importoSpecificaTextField.addFocusListener(new FocusAdapter() {
			@Override
			public void focusLost(FocusEvent arg0) {
				try{
					BigDecimal importo = new BigDecimal(importoSpecificaTextField.getText());
					if(importo.compareTo(contratto.getRimanenza()) > 0){
						JOptionPane.showMessageDialog(null, "L'importo della specifica non deve superare la rimanenza del contratto", "", JOptionPane.WARNING_MESSAGE);
						importoSpecificaTextField.setText("");
						importoSpecificaTextField.validate();
					}
				} catch (NumberFormatException e) {					
				}
				
			}
		});
		importoSpecificaTextField.setInputVerifier(new NumericInputVerifier("Importo Specifca", 15));
		GridBagConstraints gbc_importoSpecificaTextField = new GridBagConstraints();
		gbc_importoSpecificaTextField.insets = new Insets(0, 0, 5, 0);
		gbc_importoSpecificaTextField.fill = GridBagConstraints.HORIZONTAL;
		gbc_importoSpecificaTextField.gridx = 1;
		gbc_importoSpecificaTextField.gridy = 8;
		add(importoSpecificaTextField, gbc_importoSpecificaTextField);
		importoSpecificaTextField.setColumns(10);
		
		modificaSpecificaButton = new JButton("Modifica Specifica");
		modificaSpecificaButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				try {
					Specifica s = creaSpecifica();
					if(s != null){						
						int conferma = JOptionPane.showConfirmDialog(null, "Modificare la specifica?", "", JOptionPane.YES_NO_OPTION);
						if(conferma == JOptionPane.OK_OPTION){
							Specifica nuova = creaSpecifica();
							databaseController.modificaSpecifica(specifica, nuova);
							JOptionPane.showMessageDialog(null, "Specifica modificata corretamente", "", JOptionPane.INFORMATION_MESSAGE);						
						}
						
					}					
				} catch (EmptyFieldException e) {
					JOptionPane.showMessageDialog(null, e.getMessage(), "", JOptionPane.WARNING_MESSAGE);
				} catch (DatabaseConnectionException e) {
					JOptionPane.showMessageDialog(null, e.getMessage(), "", JOptionPane.WARNING_MESSAGE);
				} catch (QueryException e) {
					JOptionPane.showMessageDialog(null, e.getMessage(), "", JOptionPane.WARNING_MESSAGE);
				}
				
			}
		});
		GridBagConstraints gbc_modificaSpecificaButton = new GridBagConstraints();
		gbc_modificaSpecificaButton.anchor = GridBagConstraints.SOUTHEAST;
		gbc_modificaSpecificaButton.gridx = 1;
		gbc_modificaSpecificaButton.gridy = 9;
		add(modificaSpecificaButton, gbc_modificaSpecificaButton);
	}
	
	public Specifica creaSpecifica() throws EmptyFieldException{	    
		if(numeroSpecificaTextField.getText().length() == 0){
			throw new EmptyFieldException("Numero Specifica");
		}
		try{
			numero = new BigDecimal(numeroSpecificaTextField.getText()); 
		}catch (NumberFormatException e) {
			return null;
		}
		
		if(dataInizioSpecificaTextField.getText().length() == 0){
			throw new EmptyFieldException("Data Inizio Specifica");
		}
		try{
			dataInizio = dateFormat.parse(dataInizioSpecificaTextField.getText());
			if(dataInizio.compareTo(contratto.getDataInizio())<0){
				JOptionPane.showMessageDialog(null, "La data di inizio della specifica deve essere successiva o uguale alla data di inizio del contratto", "", JOptionPane.WARNING_MESSAGE);
				dataInizioSpecificaTextField.setText("");
				dataInizioContrattoTextField.validate();
				return null;
			}
		}catch (ParseException e) {
			return null;
		}
		
		if(termineConsegnaTextField.getText().length() == 0){
			throw new EmptyFieldException("Termine Consegna");
		}
		try{
			termineConsegna = new BigDecimal(termineConsegnaTextField.getText()); 
		}catch (NumberFormatException e) {
			return null;
		}
		
		if(dataScadenzaSpecificaTextField.getText().length() == 0){
			throw new EmptyFieldException("Data Scadenza Specifica");
		}
		try{
			dataScadenza = dateFormat.parse(dataScadenzaSpecificaTextField.getText()); 
		}catch (ParseException e) {
			return null;
		}
		
		if(importoSpecificaTextField.getText().length() == 0){
			throw new EmptyFieldException("Importo Specifica");
		}
		
		try{
			importo = new BigDecimal(importoSpecificaTextField.getText());
			if(importo.compareTo(contratto.getRimanenza()) > 0){
				JOptionPane.showMessageDialog(null, "L'importo della specifica non deve superare la rimanenza del contratto", "", JOptionPane.WARNING_MESSAGE);
				importoSpecificaTextField.setText("");
				importoSpecificaTextField.validate();
				return null;
			}
		}catch (NumberFormatException e) {
			return null;
		}
		
		Specifica s = new Specifica();
		s.setNumero(numero);
		s.setDataInizio(dataInizio);
		s.setTermineConsegna(termineConsegna);
		s.setDataScadenza(dataScadenza);
		s.setImporto(importo);
		s.setNumeroContratto(contratto.getNumero());
		return s;
	}
	
}
